﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Expires" content="86400" />
    <title>Heat Map Sample</title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        //<![CDATA[

        var floorsData;
        var selectedFloorId;

        // ページの読み込みが完了すると実行されます。
        $(function () {
            // 選択されたフロア ID を読み込みます。
            loadSelectedFloorId();

            // 凡例の色を作成します。
            var colorCount = 120;
            for (var i = 0; i < colorCount; i++) {
                $("<div></div>")
                    .addClass("legend-color")
                    .css("width", 240 / colorCount)
                    .css("left", 240 * i / colorCount)
                    .css("background-color", getHeatColor(i, colorCount - 1))
                    .appendTo(".legend-colors");
            }

            $("#selectedFloor .floor").hide();
            $(".accesspoint, .legend-color").fadeTo(0, 0.8);

            // フロアのリストのデータを定期的に取得します。
            getFloors();
            setInterval("getFloors();", 5000);

            // フロアのヒートマップにマウスが乗った場合、表示を薄くします。
            $("#floors .accesspoints").hover(
                function () { $(this).fadeTo(0, 0.5); },
                function () { $(this).fadeTo(0, 1); }
            );

            // フロアのヒートマップがクリックされた場合、そのフロアを選択状態にします。
            $("#floors .accesspoints").click(function () {
                selectedFloorId = $(this).parent(".floor").attr("floorid");
                setCookie("SelectedFloorId", selectedFloorId);
                refreshSelectedFloor();
            });
        });

        // 選択されたフロア ID を読み込みます。
        // URL のアンカー、Cookie、既定値の順に優先されます。
        function loadSelectedFloorId() {
            if (document.location.hash && document.location.hash.charAt(0) == "#") {
                selectedFloorId = document.location.hash.substring(1);
            }
            if (selectedFloorId && isValidFloorId(selectedFloorId)) {
                setCookie("SelectedFloorId", selectedFloorId);
                return;
            }

            selectedFloorId = getCookie("SelectedFloorId");
            if (selectedFloorId && isValidFloorId(selectedFloorId)) {
                return;
            }

            selectedFloorId = "A06";
        }

        // 指定されたフロア ID が有効かどうか検証します。
        function isValidFloorId(floorId) {
            return $("#floors .floor").is(function () { return $(this).attr("floorid") == floorId; });
        }

        // フロアのリストのデータを非同期的に取得します。
        function getFloors() {
            $("#busyIndicator").show();
            $("#connectionError").hide();

            $.ajax("Services/GetFloors")
                .complete(function () {
                    $("#busyIndicator").hide();
                })
                .success(function (data) {
                    var now = new Date();
                    var minute = now.getMinutes();
                    $("#getFloorsTimeText").text(format("{0}/{1} {2}:{3} の混雑状況", now.getMonth() + 1, now.getDate(), now.getHours(), minute >= 10 ? minute : "0" + minute));

                    renderFloors(data);
                })
                .error(function () {
                    $("#connectionError").show();
                });
        }

        // 画面の要素をフロアのリストのデータにバインドします。
        function renderFloors(data) {
            floorsData = data;

            $(".floor").each(function () {
                var floor = filterById(floorsData, $(this).attr("floorid"));
                if (floor == null) {
                    return;
                }

                $(this)
                // 表示用のテキストとして適さない場合は利用しません。
                //.children(".floorname").text(floor.name).end()
                    .find(".accesspoint").each(function () {
                        var ap = filterById(floor.accessPoints, $(this).attr("apid"));
                        if (ap == null) {
                            return;
                        }

                        $(this)
                            .css("background-color", getHeatColor(ap.count, parseInt($(this).attr("maxcount"))))
                            .attr("title", ap.name + ": " + ap.count + " 人");
                    });
            });

            $("#selectedFloor .floor[floorid=" + selectedFloorId + "]").fadeIn(300);
        }

        // 選択されたフロアを表示します。
        function refreshSelectedFloor() {
            if ($("#selectedFloor .floor:visible").length == 0) {
                $("#selectedFloor .floor[floorid=" + selectedFloorId + "]").fadeIn(300);
            } else {
                $("#selectedFloor .floor:visible").fadeOut(300, function () {
                    $("#selectedFloor .floor[floorid=" + selectedFloorId + "]").fadeIn(300);
                });
            }
        }
        //]]>
    </script>
    <!-- 共通ライブラリ -->
    <script type="text/javascript">
        //<![CDATA[

        // 配列の要素の中から、指定された ID を持つ要素を取得します。
        function filterById(elements, id) {
            return $(elements).filter(function () { return this.id == id; })[0];
        }

        // 数値をヒートマップ用の色に変換します。
        // 数値の範囲は、0 以上 maxValue 以下です。
        // 色は、0000FF - 00FFFF- 00FF00 - FFFF00 - FF0000 の間の連続値で表されます。
        function getHeatColor(value, maxValue) {
            if (value < 0) {
                return "rgb(0, 0, 255)"
            }
            if (value > maxValue) {
                return "rgb(255, 0, 0)";
            }

            var red =
                value < maxValue / 2 ? 0 :
                value < 3 * maxValue / 4 ? 255 * 4 * (value - maxValue / 2) / maxValue :
                255;
            var green =
                value < maxValue / 4 ? 255 * 4 * value / maxValue :
                value < 3 * maxValue / 4 ? 255 :
                255 * 4 * (maxValue - value) / maxValue;
            var blue =
                value < maxValue / 4 ? 255 :
                value < maxValue / 2 ? 255 * 4 * (maxValue / 2 - value) / maxValue :
                0;
            return format("rgb({0}, {1}, {2})", parseInt(red), parseInt(green), parseInt(blue));
        }

        // Cookie から、指定されたキーに対応する値を取得します。
        function getCookie(key) {
            if (!document.cookie) {
                return;
            }
            var entries = document.cookie.split("; ");
            for (var i = 0; i < entries.length; i++) {
                var pair = entries[i].split("=");
                if (pair[0] == key) {
                    return unescape(pair[1]);
                }
            }
        }

        // Cookie に、キーと値のペアを格納します。
        // 有効期限を 365 日後に設定します。
        function setCookie(key, value) {
            var expired = new Date();
            expired.setTime(expired.getTime() + 365 * 24 * 60 * 60 * 1000);
            document.cookie = format("{0}={1}; expires={2};", key, escape(value), expired.toGMTString());
        }

        // 指定された書式を利用して、文字列を置換します。
        function format(fmt) {
            for (var i = 1; i < arguments.length; i++) {
                var reg = new RegExp("\\{" + (i - 1) + "\\}", "g")
                fmt = fmt.replace(reg, arguments[i]);
            }
            return fmt;
        }
        //]]>
    </script>
    <style type="text/css">
        body
        {
            font-family: メイリオ, Verdana, Arial, Helvetica, sans-serif;
            font-size: 16px;
        }
        .notification
        {
            position: relative;
            margin: 12px 24px;
        }
        .notification-icon
        {
            position: absolute;
            width: 32px;
            height: 32px;
            left: 232px;
            top: -4px;
        }
        .content
        {
            position: relative;
        }
        .content .section
        {
            margin: 8px 16px;
            position: absolute;
        }
        .building
        {
            margin: 12px 12px -8px 12px;
        }
        .floor
        {
            margin: 16px 16px;
        }
        .accesspoints
        {
            position: relative;
        }
        .accesspoint
        {
            background-color: #CCCCCC;
            position: absolute;
        }
        #floors, #legend
        {
            font-size: 14px;
        }
        #floors .accesspoints
        {
            width: 240px;
            height: 60px;
            border: 1px solid #CCCCCC;
            cursor: pointer;
        }
        #selectedFloor .floorname
        {
            font-size: 20px;
        }
        #selectedFloor .accesspoints
        {
            width: 480px;
            height: 240px;
        }
        img.floor-layout
        {
            width: 480px;
            height: 240px;
        }
        .legend-colors
        {
            width: 240px;
            height: 54px;
            position: relative;
        }
        .legend-color
        {
            height: 30px;
            top: 24px;
            position: absolute;
        }
    </style>
</head>
<body>
    <h2>
        Heat Map Sample
    </h2>
    <p>
        ※ データはダミーです。5 秒間隔でデータを再取得しています。
    </p>
    <div class="notification">
        <span id="getFloorsTimeText">未接続</span>
        <img id="busyIndicator" class="notification-icon" src="Images/busy-green.gif" alt="通信中" title="通信中" />
        <img id="connectionError" class="notification-icon" src="Images/error.png" alt="通信失敗" title="通信失敗" />
    </div>
    <div class="content">
        <div id="floors" class="section" style="left: 0px; top: 0px; border: 1px solid #999999;">
            <div class="building">
                【本社ビル】
            </div>
            <div class="floor" floorid="A06">
                <div class="floorname">
                    6階
                </div>
                <div class="accesspoints">
                    <div class="accesspoint" apid="1" maxcount="10" style="width: 60px; height: 60px; left: 0px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="10" style="width: 60px; height: 60px; left: 60px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="10" style="width: 60px; height: 60px; left: 120px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="4" maxcount="10" style="width: 60px; height: 60px; left: 180px; top: 0px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A05">
                <div class="floorname">
                    5階
                </div>
                <div class="accesspoints">
                    <div class="accesspoint" apid="1" maxcount="20" style="width: 90px; height: 60px; left: 0px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="20" style="width: 60px; height: 60px; left: 90px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="20" style="width: 60px; height: 60px; left: 150px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="4" maxcount="20" style="width: 30px; height: 60px; left: 210px; top: 0px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A04">
                <div class="floorname">
                    4階
                </div>
                <div class="accesspoints">
                    <div class="accesspoint" apid="1" maxcount="15" style="width: 120px; height: 60px; left: 0px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="15" style="width: 120px; height: 30px; left: 120px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="15" style="width: 120px; height: 30px; left: 120px; top: 30px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A03">
                <div class="floorname">
                    3階
                </div>
                <div class="accesspoints">
                    <div class="accesspoint" apid="1" maxcount="15" style="width: 80px; height: 60px; left: 0px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="15" style="width: 80px; height: 60px; left: 80px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="15" style="width: 80px; height: 60px; left: 160px; top: 0px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A02">
                <div class="floorname">
                    2階
                </div>
                <div class="accesspoints">
                    <div class="accesspoint" apid="1" maxcount="15" style="width: 30px; height: 60px; left: 0px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="15" style="width: 30px; height: 60px; left: 30px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="15" style="width: 30px; height: 60px; left: 60px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="4" maxcount="15" style="width: 30px; height: 60px; left: 90px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="5" maxcount="15" style="width: 30px; height: 60px; left: 120px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="6" maxcount="15" style="width: 30px; height: 60px; left: 150px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="7" maxcount="15" style="width: 30px; height: 60px; left: 180px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="8" maxcount="15" style="width: 30px; height: 60px; left: 210px; top: 0px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A01">
                <div class="floorname">
                    1階
                </div>
                <div class="accesspoints">
                    <div class="accesspoint" apid="1" maxcount="30" style="width: 80px; height: 60px; left: 0px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="30" style="width: 80px; height: 60px; left: 80px; top: 0px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="30" style="width: 80px; height: 60px; left: 160px; top: 0px;">
                    </div>
                </div>
            </div>
            <!-- デザイン用
            <div class="floor-org" floorid="A00">
                <div class="floorname">
                    00階
                </div>
                <div class="accesspoints">
                    <div class="accesspoint" apid="1" maxcount="15" style="width: 80px; height: 60px; left: 0px; top: 0px; background-color: #00FFFF;" title="AP 1: 5 人">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="15" style="width: 80px; height: 60px; left: 80px; top: 0px; background-color: #FF0000;" title="AP 2: 20 人">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="15" style="width: 80px; height: 60px; left: 160px; top: 0px; background-color: #66FF00;" title="AP 3: 10 人">
                    </div>
                </div>
            </div>
            -->
        </div>
        <div id="selectedFloor" class="section" style="left: 320px; top: 0px;">
            <div class="floor" floorid="A06">
                <div class="floorname">
                    6階
                </div>
                <div class="accesspoints">
                    <img alt="6階 レイアウト" class="floor-layout" src="Images/layout1.gif" />
                    <div class="accesspoint" apid="1" maxcount="10" style="width: 90px; height: 150px; left: 30px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="10" style="width: 90px; height: 150px; left: 140px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="10" style="width: 90px; height: 150px; left: 250px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="4" maxcount="10" style="width: 90px; height: 150px; left: 360px; top: 45px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A05">
                <div class="floorname">
                    5階
                </div>
                <div class="accesspoints">
                    <img alt="5階 レイアウト" class="floor-layout" src="Images/layout1.gif" />
                    <div class="accesspoint" apid="1" maxcount="20" style="width: 130px; height: 150px; left: 30px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="20" style="width: 90px; height: 150px; left: 180px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="20" style="width: 90px; height: 150px; left: 290px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="4" maxcount="20" style="width: 50px; height: 150px; left: 400px; top: 45px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A04">
                <div class="floorname">
                    4階
                </div>
                <div class="accesspoints">
                    <img alt="4階 レイアウト" class="floor-layout" src="Images/layout2.gif" />
                    <div class="accesspoint" apid="1" maxcount="15" style="width: 180px; height: 180px; left: 30px; top: 30px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="15" style="width: 180px; height: 80px; left: 230px; top: 30px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="15" style="width: 180px; height: 80px; left: 230px; top: 130px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A03">
                <div class="floorname">
                    3階
                </div>
                <div class="accesspoints">
                    <img alt="3階 レイアウト" class="floor-layout" src="Images/layout2.gif" />
                    <div class="accesspoint" apid="1" maxcount="15" style="width: 120px; height: 150px; left: 40px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="15" style="width: 120px; height: 150px; left: 180px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="15" style="width: 120px; height: 150px; left: 320px; top: 45px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A02">
                <div class="floorname">
                    2階
                </div>
                <div class="accesspoints">
                    <img alt="2階 レイアウト" class="floor-layout" src="Images/layout2.gif" />
                    <div class="accesspoint" apid="1" maxcount="15" style="width: 40px; height: 150px; left: 20px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="15" style="width: 40px; height: 150px; left: 75px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="15" style="width: 40px; height: 150px; left: 130px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="4" maxcount="15" style="width: 40px; height: 150px; left: 185px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="5" maxcount="15" style="width: 40px; height: 150px; left: 240px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="6" maxcount="15" style="width: 40px; height: 150px; left: 295px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="7" maxcount="15" style="width: 40px; height: 150px; left: 350px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="8" maxcount="15" style="width: 40px; height: 150px; left: 405px; top: 45px;">
                    </div>
                </div>
            </div>
            <div class="floor" floorid="A01">
                <div class="floorname">
                    1階
                </div>
                <div class="accesspoints">
                    <img alt="1階 レイアウト" class="floor-layout" src="Images/layout2.gif" />
                    <div class="accesspoint" apid="1" maxcount="30" style="width: 120px; height: 150px; left: 40px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="2" maxcount="30" style="width: 120px; height: 150px; left: 180px; top: 45px;">
                    </div>
                    <div class="accesspoint" apid="3" maxcount="30" style="width: 120px; height: 150px; left: 320px; top: 45px;">
                    </div>
                </div>
            </div>
        </div>
        <div id="legend" class="section" style="left: 0px; top: 640px;">
            <div style="margin: 16px;">
                <div class="legend-colors">
                    <div style="position: absolute; left: 0px;">
                        少ない
                    </div>
                    <div style="position: absolute; right: 0px;">
                        多い
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>
